package com.simons.module.export;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.Map;

import org.apache.commons.io.IOUtils;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.simons.common.utils.file.PathUtil;
import com.simons.common.utils.file.office.ExcelFactory;

import lombok.extern.log4j.Log4j2;

@Service
@Log4j2
public abstract class AbstractPageExportService extends AbstractExportService{
	
	public abstract File pageExport(Map<String,Object> params, Integer limit)throws Exception;
	
	public abstract <T> Page<T> getListPage(Integer offset,Integer limit, Map<String,Object> params)throws Exception;
	
	/**
	 * 分页导出
	 */
	protected <T> File exportPage(Map<String,Object> params, Integer limit)throws Exception {
		String fileName = getFileName(exportFileNamePre);
		return this.export(params, fileName, sheetName, fieldNames, headers, limit);
	}
	
	/**
	 * 分页导出具体操作
	 */
	private <T> File export(Map<String,Object> params, String fileName, String sheetName, String[] fieldNames, String[] headers, Integer limit)throws Exception{
		// 默认第一个offset从1开始
		Integer offset = 1;
		// 数据准备
		String fileExportName = exportPlace + PathUtil.FILE_SEPARATOR + exportType + PathUtil.FILE_SEPARATOR + fileName;

		log.info("文件的路径及名字为：" + fileExportName);

		File file = new File(fileExportName);

		if (!file.exists()) {
			// 先得到文件的上级目录，并创建上级目录，在创建文件
			file.getParentFile().mkdirs();
			// 创建文件
			file.createNewFile();
		}
		// 第一个分页先查出总数
		Page<T> page = this.getListPage(offset, 1, params);
		// 设置总的workbook
		SXSSFWorkbook workbook = new SXSSFWorkbook(100);
		// 当目前是第一个页面时放行直接操作
		if(offset == 1) {
			this.doPageOpera(offset, limit, params, page, workbook, fileName);
		}
		// 当总数大于当前显示数，放行进行操作
		while(page.getTotal() >= limit * offset) {
			offset = offset + 1;
			this.doPageOpera(offset, limit, params, page, workbook, fileName);
		}
		// workbook写入文件中
		OutputStream out = null;
		try{
			out = new FileOutputStream(file);
			workbook.write(out);
			out.flush();
		}finally{
			IOUtils.closeQuietly(out);
		}
		return file;
	}
	
	private void doPageOpera(Integer offset, Integer limit, Map<String,Object> params, Page<?> page, SXSSFWorkbook workbook, String fileName)throws Exception {
		Page<?> pageInfo = this.getListPage(offset, limit, params);
		String tabSheetName =  sheetName + "(" + offset + ")";
		log.info("第" +offset + "个sheet" + tabSheetName + " sheet正在创建");
		workbook = ExcelFactory.writeExcel2007Page(workbook, fileName, tabSheetName, fieldNames, headers, pageInfo.getRecords());
	}
}
